package com.borderbears.backend.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import com.borderbears.backend.gui.dockables.ConnectionsPanel;
import com.borderbears.backend.gui.dockables.ItemViewerPanel;
import com.borderbears.backend.gui.dockables.LogPanel;
import com.borderbears.backend.gui.dockables.MetaPanel;
import com.borderbears.backend.gui.dockables.TreePanel;
import com.vlsolutions.swing.docking.DockKey;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;

public class BCBackendView extends JFrame {
	private final Logger log = Logger.getLogger(getClass().getName());

	private final DockingDesktop desk = new DockingDesktop();

	private static BCBackendView instance;

	TreePanel treePanel;
	LogPanel logPanel;
	ConnectionsPanel connectionsPanel;
	ItemViewerPanel itemViewerPanel;
	MetaPanel metaPanel;

	private BCBackendView() {

		treePanel = new TreePanel(getDefaultDockKey("Navigator"));
		logPanel = new LogPanel(getDefaultDockKey("Log"));
		connectionsPanel = new ConnectionsPanel(getDefaultDockKey("Connections"));
		itemViewerPanel = new ItemViewerPanel(getDefaultDockKey("Viewer"));
		metaPanel = new MetaPanel(getDefaultDockKey("Meta"));

		desk.addDockable(treePanel);
		desk.split(treePanel, logPanel, DockingConstants.SPLIT_BOTTOM);
		desk.split(logPanel, connectionsPanel, DockingConstants.SPLIT_RIGHT);
		desk.split(treePanel, itemViewerPanel, DockingConstants.SPLIT_RIGHT);
		desk.split(itemViewerPanel, metaPanel, DockingConstants.SPLIT_BOTTOM);

		getContentPane().add(desk);


		treePanel.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {

				itemViewerPanel.showNode(treePanel.getSelectedNode());
			}
		});

	}

	public void saveLayout(final String filename) {
		log.info("Attempting to save layout");
		try {
			final BufferedOutputStream out = new BufferedOutputStream(
					new FileOutputStream(new File(filename)));
			desk.writeXML(out);
			log.info("Layout written to "+filename);
			out.close();
			// stream isn't closed in case you'd like to save something else
			// after
		} catch (final IOException ioe) {
			log.warning("Error writing layout file: " + filename);
		}

	}

	public void loadLayout(final String filename) {
		final File f = new File(filename);
		if (!f.exists()) {
			log.warning("No layout file found, using default layout.");
			return;
		}
		try {
			final BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(f));
			desk.readXML(in);
			log.info("Layout restored.");
		} catch (final IOException e) {
			log.warning("IO Error reading layout file: "+filename);
		} catch (final ParserConfigurationException e) {
			log.warning("Error parsing layout file: "+filename);
		} catch (final SAXException e) {
			log.warning("Error parsing layout file: "+filename);
		} catch (final NullPointerException e) {
			log.warning("Nullpointer while restoring layout, removing layout file.");
			if (f.delete()) {
				log.warning("File removed: "+filename);
			} else {
				log.warning("Failed to remove: "+filename);
			}
		}
	}

	public static DockKey getDefaultDockKey(final String name) {
		final DockKey key = new DockKey(name);
		key.setAutoHideEnabled(false);
		key.setCloseEnabled(false);
		key.setMaximizeEnabled(false);
		return key;
	}

	public static BCBackendView getInstance() {
		if (null == instance) {
			instance = new BCBackendView();
		}
		return instance;
	}

}
